package com.dify.knowledge.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dify.knowledge.dto.UnansweredQuestionDTO;
import com.dify.knowledge.entity.AnswerRating;
import com.dify.knowledge.entity.ManualAnswer;
import com.dify.knowledge.entity.UnansweredQuestion;
import com.dify.knowledge.exception.RatingLimitException;
import com.dify.knowledge.repository.AnswerRatingMapper;
import com.dify.knowledge.repository.ManualAnswerMapper;
import com.dify.knowledge.repository.UnansweredQuestionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 未解答问题服务
 */
@Slf4j
@Service
public class UnansweredQuestionService {

    private final UnansweredQuestionMapper unansweredQuestionMapper;
    private final ManualAnswerMapper manualAnswerMapper;
    private final AnswerRatingMapper answerRatingMapper;

    public UnansweredQuestionService(UnansweredQuestionMapper unansweredQuestionMapper,
                                      ManualAnswerMapper manualAnswerMapper,
                                      AnswerRatingMapper answerRatingMapper) {
        this.unansweredQuestionMapper = unansweredQuestionMapper;
        this.manualAnswerMapper = manualAnswerMapper;
        this.answerRatingMapper = answerRatingMapper;
    }

    /**
     * 创建未解答问题
     * 
     * @param questionRecordId 问答记录ID
     */
    @Transactional
    public void createUnansweredQuestion(Long questionRecordId) {
        log.info("创建未解答问题，问答记录ID：{}", questionRecordId);
        
        UnansweredQuestion unansweredQuestion = new UnansweredQuestion();
        unansweredQuestion.setQuestionRecordId(questionRecordId);
        unansweredQuestion.setStatus("PENDING");
        unansweredQuestion.setCreatedAt(LocalDateTime.now());
        
        unansweredQuestionMapper.insert(unansweredQuestion);
        log.info("未解答问题已创建，ID：{}", unansweredQuestion.getId());
    }

    /**
     * 获取未解答问题列表（分页）
     * 
     * @param page 页码（从1开始）
     * @param size 每页大小
     * @return 分页结果
     */
    public Page<UnansweredQuestionDTO> getUnansweredQuestions(int page, int size) {
        log.info("获取未解答问题列表，页码：{}，每页大小：{}", page, size);
        
        Page<UnansweredQuestionDTO> pageParam = new Page<>(page, size);
        return unansweredQuestionMapper.selectUnanswered(pageParam);
    }

    /**
     * 提交人工解答
     * 
     * @param questionId 未解答问题ID
     * @param answer 解答内容
     * @param userId 解答用户ID
     * @return 创建的人工解答
     */
    @Transactional
    public ManualAnswer submitManualAnswer(Long questionId, String answer, Long userId) {
        log.info("提交人工解答，问题ID：{}，用户ID：{}", questionId, userId);
        
        ManualAnswer manualAnswer = new ManualAnswer();
        manualAnswer.setUnansweredQuestionId(questionId);
        manualAnswer.setUserId(userId);
        manualAnswer.setAnswer(answer);
        manualAnswer.setUsefulCount(0);
        manualAnswer.setUselessCount(0);
        manualAnswer.setSyncedToDify(false);
        manualAnswer.setCreatedAt(LocalDateTime.now());
        
        manualAnswerMapper.insert(manualAnswer);
        log.info("人工解答已保存，ID：{}", manualAnswer.getId());
        
        return manualAnswer;
    }

    /**
     * 对人工解答进行评分
     * 
     * @param answerId 解答ID
     * @param userId 评分用户ID
     * @param isUseful 是否有用
     */
    @Transactional
    public void rateAnswer(Long answerId, Long userId, boolean isUseful) {
        log.info("对解答评分，解答ID：{}，用户ID：{}，是否有用：{}", answerId, userId, isUseful);
        
        // 检查用户今日是否已评分
        if (hasRatedToday(answerId, userId)) {
            log.warn("用户今日已对该解答评分，用户ID：{}，解答ID：{}", userId, answerId);
            throw new RatingLimitException("您今天已经对该解答评过分了");
        }
        
        // 创建评分记录
        AnswerRating rating = new AnswerRating();
        rating.setManualAnswerId(answerId);
        rating.setUserId(userId);
        rating.setIsUseful(isUseful);
        rating.setRatingDate(LocalDate.now());
        rating.setCreatedAt(LocalDateTime.now());
        
        answerRatingMapper.insert(rating);
        log.info("评分记录已保存，ID：{}", rating.getId());
        
        // 更新人工解答的评分统计
        updateAnswerRatingCount(answerId);
    }

    /**
     * 检查用户今日是否已对某解答评分
     * 
     * @param answerId 解答ID
     * @param userId 用户ID
     * @return 是否已评分
     */
    public boolean hasRatedToday(Long answerId, Long userId) {
        LocalDate today = LocalDate.now();
        return answerRatingMapper.existsByAnswerIdAndUserIdAndDate(answerId, userId, today);
    }

    /**
     * 获取某问题的最高分答案
     * 
     * @param questionId 未解答问题ID
     * @return 最高分答案，如果没有答案则返回null
     */
    public ManualAnswer getTopRatedAnswer(Long questionId) {
        log.info("获取问题的最高分答案，问题ID：{}", questionId);
        return manualAnswerMapper.selectTopRatedByQuestionId(questionId);
    }

    /**
     * 获取某问题的所有人工解答
     * 
     * @param questionId 未解答问题ID
     * @return 人工解答列表
     */
    public List<ManualAnswer> getAnswersByQuestionId(Long questionId) {
        log.info("获取问题的所有解答，问题ID：{}", questionId);
        return manualAnswerMapper.selectByQuestionId(questionId);
    }

    /**
     * 更新人工解答的评分统计
     * 
     * @param answerId 解答ID
     */
    private void updateAnswerRatingCount(Long answerId) {
        int usefulCount = answerRatingMapper.countUsefulRatings(answerId);
        int uselessCount = answerRatingMapper.countUselessRatings(answerId);
        
        ManualAnswer answer = manualAnswerMapper.selectById(answerId);
        if (answer != null) {
            answer.setUsefulCount(usefulCount);
            answer.setUselessCount(uselessCount);
            manualAnswerMapper.updateById(answer);
            log.info("更新解答评分统计，解答ID：{}，有用：{}，无用：{}", answerId, usefulCount, uselessCount);
        }
    }
}
